home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / cshell / main.c < prev    next >
C/C++ Source or Header  |  1994-03-21  |  14KB  |  592 lines

  1. /*
  2.  * MAIN.C
  3.  *
  4.  * Matthew Dillon, 24 Feb 1986
  5.  * (c)1986 Matthew Dillon     9 October 1986
  6.  *
  7.  * Version 2.07M by Steve Drew 10-Sep-87
  8.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  9.  * Version 5.00L by U. Dominik Mueller 17-Feb-91
  10.  * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
  11.  *
  12.  */
  13.  
  14. #include "shell.h"
  15.  
  16.  
  17. #define CSH_VER "5"
  18. #define CSH_REV "37"
  19.  
  20.  
  21. static struct Window *getwindow(void);
  22. static void exectimer(int stop);
  23. char shellcompiled[]="Compiled: "__DATE__" "__TIME__" with "COMPILER"\n";
  24. #if 1
  25. char shellname[]    ="Csh "CSH_VER"."CSH_REV" (public release)";
  26. #else
  27. char shellname[]    ="Csh "CSH_VER"."CSH_REV" (BETA)";
  28. #endif
  29. char shellversion[] =CSH_VER""CSH_REV;
  30. char shellvers[]    =CSH_VER"."CSH_REV;
  31. char shellv   []    ="\0$VER: csh "CSH_VER"."CSH_REV" "__AMIGADATE__"";
  32. char shellctr []    ="CshCounter";
  33. char shellres []    ="CshResident";
  34. char shellthere[]   ="CshLoggedIn";
  35.  
  36. char *oldtitle = NULL;
  37. char trueprompt[100];
  38. char Inline[260];
  39. extern struct ExecBase *SysBase;    /* standard fare....*/
  40. extern struct DosLibrary *DOSBase;    /* more standard fare.... */
  41. struct IntuitionBase *IntuitionBase;
  42. struct GfxBase *GfxBase;
  43. struct Library *GadToolsBase;
  44. struct Library *AslBase;        /* AMK: Asl-FileRequester replaces ARP */
  45. struct Library *BattClockBase;
  46.  
  47. struct Window *old_WindowPtr = NULL;
  48. int    oldtaskpri=-999;
  49. BPTR   OldCin;
  50. void   *PatternBase;
  51. BOOL   nologout = FALSE;
  52. BOOL   nowintitle = FALSE;
  53.  
  54. #ifdef MULTIUSER_SUPPORT
  55. struct muBase  *muBase;     /* LILJA: Added for multiuser-support */
  56. #endif
  57.  
  58. static char *defset[]={
  59.     v_histnum,  "0",
  60.     v_titlebar, shellname,
  61.     v_hist,     "50",
  62.     v_lasterr,  "0",
  63.     v_stat,     "0",
  64.     v_path,     "RAM:,RAM:c,df0:c,df1:c,sys:system,csh:,s:",
  65.     v_rxpath,   "REXX:",
  66.     v_scroll,   "2",
  67.     v_minrows,  "34",
  68.     v_hilite,   "c7",
  69.     v_lcd,      "",
  70.     v_qcd,      "csh:csh-qcd",
  71.     v_insert,   "1",
  72.     v_abbrev,   "5",
  73.     "_terminal","",
  74.     "_man",     "csh:csh.doc",
  75.     "_version", shellversion,
  76. /*    v_nomatch,  "1",*/
  77.     v_prghash,  "csh:csh-prgs",
  78.     NULL,       NULL
  79. };
  80.  
  81. static char *defalias[]={
  82.     "cls",  "echo -n ^l",
  83.     "dswap","cd $_lcd",
  84.     "exit", "endcli;quit",
  85.     "cdir", "%q cd $q; cls; dir",
  86.     "q",    "quit",
  87.     "rx",   "RX",
  88.     "manlist", "search -nl $_man \"    \"",
  89.     NULL,   NULL
  90. };
  91.  
  92. struct MsgPort *Console=(struct MsgPort *)-1;
  93. long ExecTimer, ExecRC;
  94.  
  95. #ifdef __SASC
  96. long __stack = 17500L;
  97. #endif
  98.  
  99. main(int argc, char *argv[])
  100. {
  101.     static ROOT locals;
  102.     BPTR fh;
  103.     int i, login=0;
  104.     char buf[10];
  105.     BOOL nologin=FALSE,nocshrc=FALSE,noclrmenu=FALSE;
  106. #ifdef AZTEC_C
  107.     extern int Enable_Abort;
  108.     Enable_Abort = 0;
  109. #endif
  110.  
  111.     MyMem=salloc(4);
  112.  
  113.     if( argc==0 ) {              /* Prevent starting from workbench */
  114.         Delay(60);
  115.         exit(0);
  116.     }
  117.  
  118.     Myprocess = (struct Process *)FindTask(NULL);
  119.     OldCin    = Myprocess->pr_CIS;
  120.     Mycli     = Cli();
  121. /*    Mycli     = (struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2);*/
  122.  
  123.     init_mbase();
  124.     push_locals( &locals );
  125.     initmap();
  126.  
  127.     if (!SysBase || SysBase->LibNode.lib_Version<37) {
  128.         printf("Sorry, you'll need at least V37 to run CSH.\n");
  129.         exit(20);
  130.     }
  131.  
  132.     if (!DOSBase) {
  133.         printf("No dos library\n");
  134.         exit(20);
  135.     }
  136.  
  137.     /* we do not work without it ... */
  138.     DOSBase->dl_Root->rn_Flags |= RNF_WILDSTAR;
  139.  
  140.     if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))) {
  141.         printf("No graphics library\n");
  142.         exit(20);
  143.     }
  144.  
  145.     if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))) {
  146.         printf("No intuition library\n");
  147.         CloseLibrary((struct Library *)GfxBase);
  148.         exit(20);
  149.     }
  150.  
  151.     if (!(AslBase=OpenLibrary("asl.library",37L))) {
  152.         printf("No asl library\n");
  153.         CloseLibrary((struct Library *)IntuitionBase);
  154.         CloseLibrary((struct Library *)GfxBase);
  155.         exit(20);
  156.     }
  157.  
  158.     if (!(GadToolsBase=OpenLibrary("gadtools.library",37L))) {
  159.         printf("No gadtools library\n");
  160.         CloseLibrary((struct Library *)AslBase);
  161.         CloseLibrary((struct Library *)IntuitionBase);
  162.         CloseLibrary((struct Library *)GfxBase);
  163.         exit(20);
  164.     }
  165.  
  166. #ifdef MULTIUSER_SUPPORT
  167.     /* LILJA: Added for multiuser-support */
  168.     muBase = (struct muBase *) OpenLibrary("multiuser.library",39);
  169. #endif
  170.  
  171.     PatternBase = OpenLibrary("pattern.library",5L);
  172.     BattClockBase = OpenResource(BATTCLOCKNAME);
  173.  
  174.     set_var(LEVEL_SET,"_kick2x",(SysBase->LibNode.lib_Version>=37)?"1":"0");
  175.     set_var(LEVEL_SET,"_kick3x",(SysBase->LibNode.lib_Version>=39)?"1":"0");
  176.  
  177.     if( !IsInteractive(Input())) {
  178.         o_bground=1;
  179.         Mycli->cli_Background=DOSTRUE;
  180.     } else
  181.         Mycli->cli_Background=DOSFALSE;
  182.  
  183.     set_var( LEVEL_SET, v_bground, (o_bground) ? "1" : "0" );
  184.  
  185.     if( fh=Open( "CONSOLE:" , MODE_NEWFILE) ) {
  186.         Console= ((struct FileHandle *)(4*fh))->fh_Type;
  187.         Close(fh);
  188.     }
  189.  
  190.     Forbid();
  191.     i=0;
  192.     /* AMK: OS20-GetVar replaces ARP-Getenv, SetVar replaces Setenv */
  193.     if ( GetVar(shellres  ,buf,10,GVF_GLOBAL_ONLY|GVF_BINARY_VAR) >= 0L)
  194.         o_resident=1;
  195.     if ( GetVar(shellthere,buf,10,GVF_GLOBAL_ONLY|GVF_BINARY_VAR) <  0L)
  196.         login=TRUE, SetVar(shellthere,"1",-1L,GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  197.     if ( GetVar(shellctr  ,buf,10,GVF_GLOBAL_ONLY|GVF_BINARY_VAR) >= 0L)
  198.         i=atoi(buf);
  199.     sprintf(buf, "%d", i+1);
  200.     /* AMK: OS20-SetVar replaces ARP-Setenv */
  201.     SetVar(shellctr, buf, -1L, GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  202.     Permit();
  203.  
  204. #ifdef AZTEC_C
  205.     stdin->_flags    |= _IONBF;    /* make sure we're set as an unbuffered tty */
  206.     stdout->_flags    |= _IONBF;    /* in case of redirection in .login */
  207.     Close( (BPTR)_devtab[2].fd);
  208.     _devtab[2].mode |= O_STDIO;
  209.     _devtab[2].fd = _devtab[1].fd;    /* set stderr to Output() otherwise */
  210.                     /* don't work with aux driver */
  211. #else
  212.     /* if( setvbuf( stdout,NULL,_IOLBF,BUFSIZ )) exit(20); */
  213.     /* setnbf( stdout ); */
  214.     /* Close( _ufbs[2] );*/
  215.     /*_ufbs[2]=_ufbs[1]; */
  216.     /* setnbf( stderr ); */
  217. #endif
  218.  
  219.     sprintf(buf,"%ld",Myprocess->pr_TaskNum);
  220.     set_var(LEVEL_SET, "_clinumber", buf);
  221.  
  222.     seterr(0);
  223.     if (Myprocess->pr_CurrentDir == NULL)
  224.         execute("cd :");
  225.     set_cwd();
  226.  
  227.     o_nowindow= 1;
  228.  
  229.     set_var(LEVEL_SET,v_prompt, (isconsole(Input())) ? "%c%p> ":"");
  230.  
  231.     for( i=0; defset[i]; i+=2 )
  232.         set_var( LEVEL_SET, defset[i], defset[i+1] );
  233.     for( i=0; defalias[i]; i+=2 )
  234.         set_var( LEVEL_ALIAS, defalias[i], defalias[i+1] );
  235.  
  236.     o_nowindow= 0;
  237.  
  238.     for (i = 1; i < argc; ++i) {
  239.         if (*argv[i]=='-' && (index(argv[i],'a') || index(argv[i],'t')))
  240.             o_nowindow=1;
  241.         if (*argv[i]=='-' && index(argv[i],'n'))
  242.             nologin = TRUE;
  243.         if (*argv[i]=='-' && index(argv[i],'N'))
  244.             nocshrc = TRUE;
  245.         if (*argv[i]=='-' && index(argv[i],'L'))
  246.             nologout = TRUE;
  247.         if (*argv[i]=='-' && index(argv[i],'M'))
  248.             noclrmenu = TRUE;
  249.         if (*argv[i]=='-' && index(argv[i],'W'))
  250.             nowintitle = TRUE;
  251.         if (*argv[i]=='-' && index(argv[i],'R'))
  252.             o_noraw = 1;
  253.     }
  254.  
  255.     if( !o_nowindow && (Mywindow=getwindow()) && isconsole(Input())) {
  256.         old_WindowPtr = Myprocess->pr_WindowPtr;
  257.         Myprocess->pr_WindowPtr = Mywindow;
  258.         newwidth();
  259.         oldtitle=(char *)(Mywindow->Title);
  260.         if (!noclrmenu) {
  261.             /* clear menus, even if we are not the owner */
  262.             set_menu();
  263.         }
  264.     }
  265.  
  266.     if (login && !nologin) {
  267.         /*printf("we're the first csh today, mon ami!\n");*/
  268.         if( exists("S:.login"))
  269.             execute("source S:.login");
  270.     }
  271.  
  272.     if (!nocshrc) {
  273.         if( exists("S:.cshrc"))
  274.             execute("source S:.cshrc");
  275.     }
  276.  
  277.     {
  278.     char nam1[40],nam2[40],nam3[40];
  279.     BOOL e1,e2,e3;
  280.     strcpy(nam1,"ENVARC:"); strcat(nam1,shellctr);   e1=exists(nam1);
  281.     strcpy(nam2,"ENVARC:"); strcat(nam2,shellres);   e2=exists(nam2);
  282.     strcpy(nam3,"ENVARC:"); strcat(nam3,shellthere); e3=exists(nam3);
  283.  
  284.     if (e1 || e2 || e3) {
  285.         printf("\nWARNING: please remove the following files from ENVARC:\n\n");
  286.         if (e1)
  287.         printf("          - %s\n",shellctr);
  288.         if (e2)
  289.         printf("          - %s\n",shellres);
  290.         if (e3)
  291.         printf("          - %s\n",shellthere);
  292.         printf("\n         and reboot your system after removing the files.\n");
  293.         printf("         Never copy ENV: to ENVARC: !!\n\n");
  294.         Delay(150L);
  295.     }
  296.     }
  297.  
  298.     for (i = 1; i < argc; ++i) {
  299.         if (*argv[i]=='-') {
  300.             char *str=argv[i]+1;
  301.             for( ; *str; str++ ) {
  302.                 switch( *str) {
  303.                 case 'c':
  304.                 case 'C': execute( compile_av( argv, i+1, argc, ' ',*str=='C'));
  305.                           main_exit(Lastresult); break;
  306.                 case 'k': set_var(LEVEL_SET,v_nobreak,"1"); break;
  307.                 case 'v': Verbose=1; set_var(LEVEL_SET,v_verbose,"hs"); break;
  308.                 case 'b': oldtaskpri=Myprocess->pr_Task.tc_Node.ln_Pri;
  309.                           SetTaskPri( &Myprocess->pr_Task, -1 ); break;
  310.                 case 'f': oldtaskpri=Myprocess->pr_Task.tc_Node.ln_Pri;
  311.                           SetTaskPri( &Myprocess->pr_Task,  1 ); break;
  312.                 case 'a': o_nowindow= o_noraw= 1;
  313.                           set_var( LEVEL_SET, v_hilite, "" ); break;
  314. #if 0
  315.                 case 'm': unset_var(LEVEL_SET,v_nomatch); break;
  316. #endif
  317.                 case 'm': set_var(LEVEL_SET,v_nomatch,"1"); break;
  318.                 case 't': o_nowindow= o_vt100= o_nofastscr= 1;
  319.                           set_var( LEVEL_SET, v_hilite, "r" );
  320.                           set_var( LEVEL_SET, v_noreq, "1" );
  321.                           set_var( LEVEL_SET, "_terminal", "1" );
  322.                           set_var( LEVEL_ALIAS, "cls", "e -n ^[[0\\;0H^[[J" );
  323.                           break;
  324.                 case 's': DOSBase->dl_Root->rn_Flags |= RNF_WILDSTAR;
  325.                           break;
  326.                 }
  327.             }
  328.         } else {
  329.             sprintf (Inline, "source %s",argv[i]);
  330.             execute (Inline);
  331.         }
  332.     }
  333.  
  334.     if( !isconsole(Input()))
  335.         main_exit( Lastresult );
  336.  
  337.     for (;;) {
  338.         if (breakcheck())
  339.             while (WaitForChar(Input(), 100L) || CHARSWAIT( stdin ))
  340.                 gets(Inline);
  341.         clearerr(stdin);  /* prevent acidental quit */
  342.         /*
  343.            AMK: new position of breakreset() before exec_every(),
  344.                 old position caused enforcer hits
  345.                 (do 'set _every "set cols = $(wincols)"' and
  346.                  then abort (^c) a command)
  347.         */
  348.         breakreset();
  349.         exec_every();
  350.  
  351.         { /* AMK TEST BEGIN */
  352.             char *old;
  353.             char pwd[256];
  354.  
  355.             /* no requesters when no disk is inserted */
  356.             Myprocess->pr_WindowPtr = (APTR)(-1);
  357.  
  358. #if 1
  359.             if (NameFromLock(Myprocess->pr_CurrentDir, pwd, 255L)) {
  360.                 if( !(old=get_var(LEVEL_SET, v_cwd)) )
  361.                     old="";
  362.                 if (strcmp(pwd,old)) {
  363.                     set_var(LEVEL_SET, v_lcd, old);
  364.                     set_cwd();
  365.                 }
  366.             }
  367. #else
  368.             if (!NameFromLock(Myprocess->pr_CurrentDir, pwd, 255L)) {
  369.                 fprintf(stderr,"csh.main: NameFromLock() failed\n");
  370.                 strcpy(pwd,"<unknown>");
  371.             }
  372.             if( !(old=get_var(LEVEL_SET, v_cwd)) )
  373.                 old="";
  374.             if (strcmp(pwd,old)) {
  375.                 set_var(LEVEL_SET, v_lcd, old);
  376.                 set_cwd();
  377.             }
  378. #endif
  379.             /*update_sys_var(v_cwd);*/
  380.  
  381.             Myprocess->pr_WindowPtr = o_noreq ? (APTR) -1L : Mywindow;
  382.  
  383.         } /* AMK TEST BEGIN */
  384.  
  385.         update_sys_var(v_titlebar);
  386.         update_sys_var(v_prompt);
  387.         /*
  388.            AMK: old position of breakreset(), causes enforcer hits
  389.                 (do 'set _every "set cols = $(wincols)"' and
  390.                  then abort (^c) a command)
  391.         */
  392.         breakreset();
  393. #if RAW_CONSOLE
  394.         if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0);
  395. #else
  396.         printf("%s", disable ? "_ " : trueprompt);
  397.         fflush(stdout);
  398.         if (Quit || !gets(Inline)) main_exit(0);
  399. #endif
  400.         breakreset();
  401.         exectimer(0);
  402.         if (*Inline) ExecRC=exec_command(Inline);
  403.         exectimer(1);
  404.     }
  405. }
  406.  
  407.  
  408. void
  409. main_exit(n)
  410. {
  411.     int i;
  412.     char buf[10];
  413.  
  414.     /* AMK: OS20-GetVar replaces ARP-Getenv */
  415.     GetVar(shellctr,buf,10L,GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  416.     i=atoi(buf);
  417.     sprintf(buf,"%d",i-1);
  418.     /* AMK: OS20-SetVar replaces ARP-Setenv */
  419.     SetVar(shellctr, buf, -1L, GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  420.  
  421.     if( oldtitle )
  422.         SetWindowTitles(Mywindow,oldtitle,(char *)-1);
  423.     if( oldtaskpri != -999 )
  424.         SetTaskPri(&Myprocess->pr_Task,oldtaskpri);
  425.  
  426.     if (Mywindow)
  427.         Myprocess->pr_WindowPtr = old_WindowPtr;
  428.  
  429.     for (i=1; i<MAXMYFILES; i++) myclose(i);
  430.  
  431.     /* no effect if AnzMenus==0 (no menus in use) */
  432.     remove_menu();
  433.  
  434. #ifdef MULTIUSER_SUPPORT
  435.     /* LILJA: Added for multiuser-support */
  436.     if (muBase) CloseLibrary((struct Library *)muBase);
  437. #endif
  438.  
  439.     if (PatternBase) CloseLibrary( PatternBase );
  440.     CloseLibrary((struct Library *)GadToolsBase);
  441.     CloseLibrary((struct Library *)AslBase);
  442.     CloseLibrary((struct Library *)IntuitionBase);
  443.     CloseLibrary((struct Library *)GfxBase);
  444.     exit(n);
  445. }
  446.  
  447.  
  448. static void
  449. exectimer(int stop)
  450. {
  451.     struct DateStamp dss;
  452.     static long lasttime;
  453.     long time;
  454.  
  455.     DateStamp(&dss);
  456.     time=dss.ds_Minute*6000+2*dss.ds_Tick;   /* 2 = 100/TickPerSec   */
  457.     if( stop )
  458.         ExecTimer=time-lasttime;
  459.     else
  460.         lasttime=time;
  461. }
  462.  
  463.  
  464. /* print break message only once */
  465. static BOOL dobreak_output = TRUE;
  466.  
  467. int
  468. breakcheck()
  469. {
  470.     return !o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_C;
  471. }
  472.  
  473. void
  474. breakreset()
  475. {
  476.     /* We reset CTRL_E here for GMD's foreach() hack ... */
  477.     /* Why not just reset CTRL_F also -- for completeness? :) */
  478.  
  479.     SetSignal(0L, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E);
  480.     dobreak_output = TRUE;
  481. }
  482.  
  483. dobreak()
  484. {
  485.     if (breakcheck()) {
  486.         if (dobreak_output) {
  487.             printf("^C\n");
  488.             dobreak_output = FALSE;
  489.         }
  490.         return(1);
  491.     }
  492.     return(0);
  493. }
  494.  
  495. /* this routine causes manx to use this Chk_Abort() rather than it's own */
  496. /* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
  497. /* is zero).  Since we want to check for our own ^C's             */
  498.  
  499. long
  500. Chk_Abort()
  501. {
  502.     return(0);
  503. }
  504.  
  505. void
  506. _wb_parse()
  507. {
  508. }
  509.  
  510. do_howmany()
  511. {
  512.     char buf[10];
  513.  
  514.     /* AMK: OS20-GetVar replaces ARP-Getenv */
  515.     GetVar(shellctr, buf, 10L, GVF_GLOBAL_ONLY|GVF_BINARY_VAR);
  516.     printf("Shell(s) running: %s\n",buf);
  517.     return 0;
  518. }
  519.  
  520. static struct Window *
  521. getwindow(void)
  522. {
  523.     struct Window *win = NULL;
  524.  
  525.     if( o_nowindow )
  526.         return NULL;
  527.     if( isconsole(Output()))
  528.         Write(Output(),"",1);     /*    make window appear */
  529.     if( Myprocess->pr_ConsoleTask ) {
  530.         struct InfoData *infodata;
  531.         infodata=(void *)SAllocMem((long)sizeof(struct InfoData),MEMF_CLEAR|MEMF_PUBLIC);
  532.         if (DoPkt((void *)Myprocess->pr_ConsoleTask,ACTION_DISK_INFO,((LONG)infodata)>>2,NULL,NULL,NULL,NULL)) {
  533.             win=(struct Window *)infodata->id_VolumeNode;
  534.         }
  535.         FreeMem(infodata,sizeof(struct InfoData));
  536.         if( win==NULL )
  537.             o_nowindow=1;
  538.     }
  539.     newwidth();
  540.     return win;
  541. }
  542.  
  543.  
  544. #ifdef LATTICE
  545.  
  546. int
  547. setenv( char *var, char *val )
  548. {
  549.     char *buf=salloc(strlen(var)+strlen(val)+10);
  550.     sprintf(buf, "%s=%s", var, val );
  551.     Free(buf);
  552.     return putenv(buf);
  553. }
  554.  
  555. __regargs int __chkabort(void) { return(0); }
  556.  
  557. #endif
  558.  
  559. #ifdef _DCC
  560. void
  561. swapmem(void *_s1, void *_s2, size_t _n)
  562. {
  563.     char t, *s1=_s1, *s2=_s2;
  564.     int  i;
  565.  
  566.     for( i=0; i<_n; i++ )
  567.         t=*s1; *s1++=*s2; *s2++=t;
  568. }
  569.  
  570. int
  571. setenv( char *var, char *val )
  572. {
  573.     BPTR fh;
  574.     char buf[40];
  575.     sprintf(buf,"ENV:%s",var );
  576.  
  577.     if( fh=Open(buf,MODE_NEWFILE) ) {
  578.         Write(fh,val,strlen(val));
  579.         Close(fh);
  580.     }
  581. }
  582.  
  583. int
  584. rand()
  585. {
  586.     return 0;
  587. }
  588.  
  589. _waitwbmsg() {return 0;};
  590.  
  591. #endif
  592.